
/* Program to effectively perform an RMEnsure in the manner described
   in the docs. This does the appropriate 'soft' loading.

   by Rick Hudson, 1999
   modified by Christopher Martin, 2012
*/


#ifndef _playit_ensure_c
#define _playit_ensure_c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "kernel.h"

#include "playitap.h"

typedef char bool;
#define FALSE 0
#define TRUE 1

#define Xbit                      0x20000
#define Wimp_Initialise    0x400C0
#define Wimp_CloseDown     0x400DD

#define SWI(swi,in,out) (playit_error*)_kernel_swi(swi,in,out)


static playit_error serr;

static playit_error *MakeStaticError(char *mess)
{
   serr.errnum=0;
   strcpy(serr.errmess,mess);
   return &serr;
}


int main(int argc, char *argv[])
{
   int minver,version;
   char sver[8], respath[256] = "PlayIt:";  /* Note the default resource path */
   playit_error *err = NULL;
   int par=1;
   bool errvar = FALSE;
   _kernel_swi_regs r;

   if (argv[par][0]=='-' && tolower(argv[par][1])=='e' && !argv[par][2]) {
      errvar=TRUE;
      par++;
   }
   if (par>=argc) err=MakeStaticError("Syntax: Ensure [-e] <min version> [<driver leaf>]");
    else if (sscanf(argv[par], "%d.%d", &minver, &version)==2)
       minver = minver*100+version;
   if (!err) if (minver<0 || minver>299) err=MakeStaticError("Bad version number");

   /*
      If this program was found by a path, that path will be taken to be the resource path!
      Only if there was no path to the executable will the default resource path be used.
   */
   {
      register char *p0 = argv[0];
      register char *pc;
      register int i;
      for (pc = &p0[strlen(p0) - 1]; (pc >= p0) && (*pc != '.') && (*pc != ':'); --pc);
      /* At this moment, pc points to either the last '.' or ':', or *behind* the path. */
      if ((i = pc - p0) >= 0) {
         strcpy(respath, p0);
         respath[i + 1] = '\0';
      }
   }

   if (!err) {
      int taskh=0;
      bool wimpok = getenv("Desk$State") != NULL;
      if (wimpok) {
         r.r[0]=310;
         r.r[1]=0x4B534154;
         r.r[2]=(int)"PlayIt Ensure";
         r.r[3]=0;
         if (!SWI(Wimp_Initialise|Xbit, &r, &r)) wimpok=TRUE;
         taskh=r.r[1];
      }
      err=xplayit_ensure(minver, respath, wimpok, &version);
      if (wimpok) {
         r.r[0]=taskh;
         r.r[1]=0x4B534154;
         SWI(Wimp_CloseDown|Xbit, &r, &r);
      }
   }
   if (err) version=0;
   else if (++par<argc) {
      err=xplayit_load_driver(strcat(respath, argv[par]));
   }

   sprintf(sver, "%d", version);
   _kernel_setenv("PlayIt$Version", sver);
   if (err) {
      if (!errvar) fprintf(stderr,"%s\n", err->errmess);
      else _kernel_setenv("PlayIt$Error", err->errmess);
   }
   exit(err ? EXIT_FAILURE:EXIT_SUCCESS);
}


#endif
